package ecoll.server;

import java.util.ArrayList;
import java.util.Date;

import com.google.appengine.api.blobstore.BlobKey;
import com.google.appengine.api.datastore.DatastoreService;
import com.google.appengine.api.datastore.DatastoreServiceFactory;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.KeyFactory;
import com.google.appengine.api.datastore.PreparedQuery;
import com.google.appengine.api.datastore.Query;
import com.google.appengine.api.datastore.Query.FilterPredicate;
import com.google.appengine.api.datastore.Query.SortDirection;

import ecoll.client.dictionary.Definition;

public abstract class Database {

	public static Entity getRights(Key fileKey, String user) {
		Key userKey = KeyFactory.createKey("UserEntity", user);
		Query q = new Query("FileRightsEntity").setAncestor(userKey)
				.setFilter(
						new FilterPredicate("file", Query.FilterOperator.EQUAL,
								fileKey));
		PreparedQuery pq = DatastoreServiceFactory.getDatastoreService()
				.prepare(q);
		return pq.asSingleEntity();
	}

	public static Key putRights(Key userKey, Key fileKey, Date date,
			String value) {
		Entity rights = new Entity("FileRightsEntity", userKey);
		rights.setProperty("file", fileKey);
		rights.setProperty("date", date);
		if (!value.equals("r") && !value.equals("w") && !value.equals("o")) {
			// r - read, w - read and write, o - ownership rights
			return null;
		}
		rights.setProperty("rights", value);
		DatastoreServiceFactory.getDatastoreService().put(rights);
		return rights.getKey();
	}

	public static ArrayList<Definition> getDefinitions(long fileId)
			throws RuntimeException {
		Key fileKey = KeyFactory.createKey("FileEntity", fileId);
		Entity fileRights = Database.getRights(fileKey, Server.getUser());
		if (fileRights == null)
			throw new RuntimeException("Unauthorized operation");

		Query query = new Query("DefinitionEntity").setAncestor(fileKey);
		query.addSort("word", SortDirection.ASCENDING);

		PreparedQuery pq = DatastoreServiceFactory.getDatastoreService()
				.prepare(query);

		ArrayList<Definition> defList = new ArrayList<Definition>();
		for (Entity result : pq.asIterable()) {
			String word = (String) result.getProperty("word");
			String wordClass = (String) result.getProperty("class");
			ArrayList<String> synonyms = (ArrayList<String>) result
					.getProperty("synonyms");
			String meaning = (String) result.getProperty("meaning");
			Definition definition = new Definition(word, wordClass, synonyms,
					meaning);
			defList.add(definition);
		}
		return defList;
	}

	public static void putDefinitions(ArrayList<Definition> definitions, long fileId) {
		Key userKey = KeyFactory.createKey("UserEntity", Server.getUser());

		Key fileKey = KeyFactory.createKey("FileEntity", fileId);
		Entity fileRights = Database.getRights(fileKey, Server.getUser());
		if (fileRights == null || fileRights.getProperty("rights").equals("r"))
			throw new RuntimeException("Unauthorized operation");

		DatastoreService datastore = DatastoreServiceFactory
				.getDatastoreService();
		for (Definition d : definitions) {
			Entity definition = new Entity("DefinitionEntity", fileKey);
			definition.setProperty("user", userKey);
			definition.setProperty("word", d.getWord());
			definition.setProperty("class", d.getWordClass());
			definition.setProperty("meaning", d.getMeaning());
			definition.setProperty("synonyms", d.getSynonyms());
			datastore.put(definition);
		}
	}

	public static Key putFile(BlobKey blobKey, Date date) {
		Entity file = new Entity("FileEntity");
		file.setProperty("blobKey", blobKey);
		file.setProperty("date", date);
		DatastoreServiceFactory.getDatastoreService().put(file);
		return file.getKey();
	}
}
